#include "VertexBuffer.h"
#include <iostream>



int VertexBuffer::updateBuffer() {

#ifdef _OPENGL

	glGenBuffers(hasAdditionalData() ? 2:1, &m_BufferInfo.vertexVBOID);
	glBindBuffer(GL_ARRAY_BUFFER, m_BufferInfo.vertexVBOID);
	glBufferData(GL_ARRAY_BUFFER, m_VertexCount*sizeof(DeviceVertexData), m_DeviceVertexData, glBufferUsageFlag());

	if(glGetError() == GL_OUT_OF_MEMORY) {
		std::cerr << "Not enough device memory to create the vertex buffer" << std::endl;
		return 1;
	}

	if(hasAdditionalData()) {
		glBindBuffer(GL_ARRAY_BUFFER, m_BufferInfo.additionalVBOID);
		glBufferData(GL_ARRAY_BUFFER, m_VertexCount*sizeof(DeviceAdditionalUVData), m_DeviceAdditionalData, glBufferUsageFlag());

		if(glGetError() == GL_OUT_OF_MEMORY) {
			std::cerr << "Not enough device memory to create the additional texture buffer" << std::endl;
			return 2;
		}
	}


#endif

#ifdef _DIRECTX
	// TODO: DX VertexBuffer.updateBuffer()
#endif

	return 0;

}

void VertexBuffer::releaseBuffer() {

#ifdef _OPENGL
	glDeleteBuffers(hasAdditionalData() ? 2:1, &m_BufferInfo.vertexVBOID);
#endif

#ifdef _DIRECTX
	// TODO: DX VertexBuffer.releaseBuffer()
#endif

}

int VertexBuffer::sendToPipeline(unsigned int textureCoordinates) {

#ifdef _OPENGL
	
	glBindBuffer(GL_ARRAY_BUFFER, m_BufferInfo.vertexVBOID);
	glVertexPointer(3, GL_FLOAT, sizeof(DeviceVertexData), BUFFER_OFFSET(0));
	glNormalPointer(GL_FLOAT, sizeof(DeviceVertexData), BUFFER_OFFSET(3*sizeof(float)));

	if(textureCoordinates == 0 || !hasAdditionalData()) {
		glTexCoordPointer(2, GL_FLOAT, sizeof(DeviceVertexData), BUFFER_OFFSET(6*sizeof(float)));	
	}
	else {
		glBindBuffer(GL_ARRAY_BUFFER, m_BufferInfo.additionalVBOID);
		glTexCoordPointer(2, GL_FLOAT, sizeof(DeviceAdditionalUVData), 
			BUFFER_OFFSET((textureCoordinates-1)*sizeof(DeviceUVData)));
	}

#endif

#ifdef _DIRECTX
	// TODO: DX VertexBuffer.sendToPipeline()
#endif

	return 0;
}

void VertexBuffer::setupPipeline() {

#ifdef _OPENGL
	
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

#endif

#ifdef _DIRECTX
	// TODO: DX VertexBuffer.sendToPipeline()
#endif

}

void VertexBuffer::releasePipeline() {

#ifdef _OPENGL
	
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

#endif

#ifdef _DIRECTX
	// TODO: DX VertexBuffer.sendToPipeline()
#endif

}